/* lolev_env.c - funções de configuração da camada de baixo nível
 * responsável pelo canal virtual.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "lolev_env.h"

/*
#include <unistd.h>
#include <linux/types.h>
#include <sys/types.h>
#include <netinet/tcp.h>
 */

/* Variáveis globais utilizadas  */
int endpoint_is_active   = 0;
int endpoint_is_passive  = 0;
int lolev_env_mtu;

unsigned int   local_port;
unsigned int   remote_port;
char*          remote_host_name;
struct hostent remote_host;

/* Declaração das funções locais necessárias */

void getenv_mode(void);
void getenv_remote_host(void);
int  getenv_port(char* env_port);
void getenv_mtu(void);

/* Definição da função declarada em lolev_env.h */

void getenv_vars(void)
{
    getenv_mode();
    getenv_mtu();
    local_port  = getenv_port(ENV_LOCAL_PORT);
    remote_port = getenv_port(ENV_REMOTE_PORT);
    getenv_remote_host();
}

/* Definição das funções locais */

void getenv_mode(void) 
{
    char* evar;

    if ((evar=getenv(ENV_MODE))==NULL) {
        fprintf(stderr,"lolev_init: mode env var (%s) not defined\n",ENV_MODE);
        fprintf(stderr,"            expected values: \"%s\" or \"%s\"\n",
                ENV_MODE_ACTIVE, ENV_MODE_PASSIVE);
        exit(1);
    }

    if (!strcmp(evar,ENV_MODE_ACTIVE)) {
        endpoint_is_active  = TRUE;
        fprintf(stderr,"lolev_init: endpoint is active\n");
    } else if (!strcmp(evar,ENV_MODE_PASSIVE)) {
        endpoint_is_passive = TRUE;
        fprintf(stderr,"lolev_init: endpoint is passive\n");
    } else {
        fprintf(stderr,"lolev_init: mode env var (%s) not valid: \"%s\"\n",
                ENV_MODE, evar );
        fprintf(stderr,"            expected values: \"%s\" or \"%s\"\n",
                ENV_MODE_ACTIVE, ENV_MODE_PASSIVE);
        exit(1);
    }
}

void getenv_mtu(void)
{
    char* evar;

    if ((evar=getenv(ENV_MTU))==NULL) {
        fprintf(stderr,"lolev_init: mode env var (%s) not defined\n",ENV_MTU);
        fprintf(stderr,"            expected values: [%d,%d]\n",
                MINMTU,MAXMTU);
        exit(1);
    }

    lolev_env_mtu = atoi(evar);
    if ((lolev_env_mtu <MINMTU)||(lolev_env_mtu >MAXMTU)) {
        fprintf(stderr,"lolev_init: mode env var (%s) not valid: \"%s\"\n",
                ENV_MTU,evar);
        fprintf(stderr,"            expected values: [%d,%d]\n",
                MINMTU,MAXMTU);
        exit(1);
    }
    fprintf(stderr,"lolev_init: using %s %d\n", ENV_MTU,lolev_env_mtu );
}

void getenv_remote_host(void) 
{
    struct hostent* he;

    if ((remote_host_name=getenv(ENV_REMOTE_HOST))==NULL) {
        fprintf(stderr,"lolev_init: mode env var (%s) not defined\n",
                ENV_REMOTE_HOST);
        fprintf(stderr,"            expected a host name or IP number\n");
        exit(1);
    }
    if ((he=gethostbyname(remote_host_name))==NULL) {
        fprintf(stderr,"lolev_init: %s value (%s) is not a host\n",
                ENV_REMOTE_HOST,remote_host_name);
        exit(1);
    }
    fprintf(stderr,"lolev_init: other host is %s (%s)\n",
            remote_host_name, inet_ntoa(*((struct in_addr*)he->h_addr)) );
    remote_host = *he;
}    

int getenv_port(char* env_port)
{
    char* evar;
    int   port;

    if ((evar=getenv(env_port))==NULL) {
        fprintf(stderr,"lolev_init: mode env var (%s) not defined\n",env_port);
        fprintf(stderr,"            expected values: [%d,%d]\n",
                MINPORT,MAXPORT);
        exit(1);
    }

    port= atoi(evar);
    if ((port<MINPORT)||(port>MAXPORT)) {
        fprintf(stderr,"lolev_init: mode env var (%s) not valid: \"%s\"\n",
                env_port,evar);
        fprintf(stderr,"            expected values: [%d,%d]\n",
                MINPORT,MAXPORT);
        exit(1);
    }
    fprintf(stderr,"lolev_init: using %s %d\n", env_port,port);
    return port;
}
